package zunge.twidel.typo;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

import zunge.tool.db.sql.DbConn;
import zunge.twidel.typo.TPairPool.TPair;

public class Main_Tuning {

	static final String logFile = "/Users/bliu1/Desktop/tuning.log";
	
	public static void main(String args[]){
		try{
			//generateSamples();
			tuning();
		}catch(Exception e){e.printStackTrace();}
	}
	
	static final int sampleSize = 200;
	static int startPoint = 0;
	
	public static void generateSamples() throws Exception{
		int goodCount = 0;
		int badCount = 0;
		
		List<String> lines = new ArrayList<String>();
		/*
		BufferedReader br = new BufferedReader(new FileReader(logFile));
		String line;
		while((line=br.readLine())!=null){
			lines.add(line);
		}
		br.close();
		*/
		
		TPairPool pool = new TPairPool(startPoint);
		BufferedWriter bw = new BufferedWriter(new FileWriter(logFile));
		for(String s:lines){
			int flag = Integer.parseInt(s.charAt(0)+"");
			if(flag==0){goodCount++;}
			else if(flag==1){badCount++;}
			bw.write(s+"\n");
			bw.flush();
		}
		boolean proceed = false;
		
		BufferedReader bri = new BufferedReader(new InputStreamReader(System.in));
		
		while(goodCount < sampleSize || badCount < sampleSize){
			TPair pair = pool.getTweetPair(proceed);
			System.out.println(pair.t1+"\n\n"+pair.t2+"\n");
			
			int flag = 2;
			try{
				flag = Integer.parseInt(bri.readLine());
			}catch(Exception e){}
			
			if(flag == 0 && goodCount<sampleSize){
				bw.write("0\t"+pair.t1+"\t"+pair.t2+"\n");
				bw.flush();
				goodCount++;
				proceed = true;
			}
			else if(flag == 1 && badCount<sampleSize){
				bw.write("1\t"+pair.t1+"\t"+pair.t2+"\n");
				bw.flush();
				badCount++;
				proceed = true;
			}
			else{
				proceed = false;
			}
		}
	}
	
	static void tuning() throws Exception{
		List<Point> points = new ArrayList<Point>();
		
		BufferedReader br = new BufferedReader(new FileReader(logFile));
		String line;
		while((line=br.readLine())!=null){
			String[] frags = line.split("\t");
			try{
				points.add(new Point(Integer.parseInt(frags[0]),frags[1],frags[2]));
			}catch(Exception e){}
		}
		

		List<Param> params = new ArrayList<Param>();
		int[] Ts = {2,3,4,5,6,7,8};
		double[] Rs = {0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1};
		int[] LENs = {5,6,7,8,9,10,15,20};
		int[] Ls = {1,2,3,4,5,6,7,8};
		
		/*
		for(int t = 0;t < Ts.length;++t)
			for(int r = 0;r < Rs.length;++r)
				for(int len = 0;len < LENs.length;++len)
					for(int l = 0;l < Ls.length;++l){
						params.add(new Param(Ts[t],Rs[r],LENs[len],Ls[l]));
					}
		*/
		params.add(new Param(4,0.6,10,8));
		
		for(Param param:params){
			TypoCheck tc = new TypoCheck(param.T,param.R,param.LEN,param.L);
			double total = 0;
			double error = 0;
			double bad = 0;
			for(Point point:points){
				total++;
				int label = tc.typoCheck(point.t1, point.t2);
				if(point.label + label > 0 && point.label * label == 0){
					error++;
				}
				if(point.label>0 && label>0){
					bad++;
				}
			}
			param.accuracy = error/total;
			param.coverage = bad;
		}
		
		Collections.sort(params);
		for(Param param:params){
			System.out.println(param.T+"\t"+param.R+"\t"
					+param.LEN+"\t"+param.L+"\t"
					+param.accuracy+"\t"+param.coverage);
		}
	}
	
	public static class Point{
		int label;
		String t1;
		String t2;
		public Point(int label, String t1, String t2) {
			super();
			this.label = label;
			this.t1 = t1;
			this.t2 = t2;
		}
	}
	public static class Param implements Comparable<Param>{
		public int T;		//Threshold for edit distance
		public double R;	//Threshold for cosine similarity
		public int LEN;	//Minimal tweet length to calculate edit distance
		public int L;
		public Double accuracy;
		public double coverage;
		public Param(int t, double r, int lEN, int l) {
			super();
			T = t;
			R = r;
			LEN = lEN;
			L = l;
		}
		@Override
		public int compareTo(Param arg0) {
			return this.accuracy.compareTo(arg0.accuracy);
		}
	}
}
